package e.odbo.data.generate.code;

import e.odbo.data.bean.CreateDateAble;
import e.odbo.data.bean.ModifiedLogAble;
import e.odbo.data.generate.GenerateConfig;
import e.odbo.data.generate.code.model.ColumnMeta;
import e.odbo.data.generate.code.model.TableMeta;
import org.jumpmind.db.model.Column;
import org.jumpmind.db.model.ForeignKey;
import org.jumpmind.db.model.Reference;
import org.jumpmind.db.model.Table;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import org.jumpmind.db.platform.PlatformUtils;

import java.io.File;
import java.io.StringWriter;
import java.sql.Types;


public class BeanClass extends AbstractCodeClass {
    public TableMeta tableMeta;

    public BeanClass(Table table, GenerateConfig config) {
        super(table, config);

        tableMeta = new TableMeta();
        tableMeta.setBasePackageName(config.basePackage);
        tableMeta.setTableName(table.getName());

        int columnIndex = 0;
        for (Column column : table.getColumns()) {

            ColumnMeta columnMeta = new ColumnMeta();
            columnMeta.setColumnName(column.getName());
            columnMeta.setColumnComment(column.getDescription());
            columnMeta.setColumnType(getOdboFieldType(column));
            tableMeta.addColumn(columnMeta);
            if (ModifiedLogAble.LASTMODIFIED.equalsIgnoreCase(column.getName())) {
                tableMeta.setModifiedLogAble(true);
                tableMeta.addImportInterface("e.odbo.data.bean.ModifiedLogAble");
            } else if (CreateDateAble.CREATEDATE.equalsIgnoreCase(column.getName())) {
                tableMeta.setCreateDateAble(true);
                tableMeta.addImportInterface("e.odbo.data.bean.CreateDateAble");
            }
            if (column.isAutoIncrement()) {
                tableMeta.setAutoGeneratorID(true);
                tableMeta.setIdIndex(columnIndex);
                tableMeta.addImportInterface("e.odbo.data.bean.I_AutoGeneratorStringKey");
            }
            columnIndex++;
        }

        for (ForeignKey foreignKey : table.getForeignKeys()) {
            String foreignClass = TableMeta.getClassName(foreignKey.getForeignTableName());
            tableMeta.addImportBeanClass(config.basePackage + ".bean." + foreignClass);
            //如果有多个列引用一个表，那么就不处理，让用户自行扩展后定义。。。
            //for(Reference reference:foreignKey.getReferences()) {
            if (foreignKey.getReferences().length == 1) {
                Reference reference = foreignKey.getReferences()[0];
                ColumnMeta columnMeta = tableMeta.getColumnByName(reference.getForeignColumnName());
                columnMeta.setRefClassName(foreignClass);
            }
        }
    }

    @Override
    public String generateClass(Configuration cfg, String modelName) {
        StringWriter writer = null;
        try {
            System.out.println("load template for:");
            String tplDir = getClass().getResource("/template/" + modelName).getPath();
            System.out.println("load template for:" + tplDir);
            cfg.setDirectoryForTemplateLoading(new File(tplDir));
            Template tpl = cfg.getTemplate("bean.ftl");
            writer = new StringWriter();
            tpl.process(tableMeta, writer);
        } catch (Exception e) {
            System.out.println(e);
            return null;
        }
        System.out.println("===文件 " + tableMeta.getClassName() + ".java" + " 生成成功===");
        return writer.toString();
    }

    public static String getOdboFieldType(Column column) {
        switch (column.getMappedTypeCode()) {
            case Types.TINYINT:
            case Types.SMALLINT:
                //return new Short(defaultValue);

            case Types.INTEGER:
                /**try {
                 return new Integer(defaultValue);
                 } catch (NumberFormatException e) {
                 return new Long(defaultValue);
                 }**/
                return "INT";//Datas.INT;
            case Types.BIGINT:
                //return new Long(defaultValue);
                return "LONG";//Datas.LONG;
            case Types.DECIMAL:
            case Types.NUMERIC:
                //return new BigDecimal(defaultValue);
                return "DOUBLE";//Datas.DOUBLE;
            case Types.REAL:
                //return new Float(defaultValue);
            case Types.DOUBLE:
            case Types.FLOAT:
                //return new Double(defaultValue);
                return "DOUBLE";//Datas.DOUBLE;
            case Types.DATE:
                //return Date.valueOf(defaultValue);
            case Types.TIME:
                //return Time.valueOf(defaultValue);
            case Types.TIMESTAMP:
                //return Timestamp.valueOf(defaultValue);
                return "TIMESTAMP";//Datas.TIMESTAMP;
            case Types.BIT:
                //return FormatUtils.toBoolean(defaultValue);
                return "BOOLEAN";//Datas.BOOLEAN;
            case Types.VARCHAR:
                return "STRING";//Datas.STRING;
            default:
                if (PlatformUtils.supportsJava14JdbcTypes()
                        && (column.getMappedTypeCode() == PlatformUtils.determineBooleanTypeCode())) {
                    //return FormatUtils.toBoolean(defaultValue);
                    return "BOOLEAN";//Datas.BOOLEAN;
                }
                break;
        }
        return "";
    }


}
